package com.zx.cloud.util;

import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

public final class RegexUtils {

	private static final String chinese_regexp = "^[\u4E00-\u9FA5]+$";
	private static final String blankSpace_regexp = "\\s+";
	private static final String ip_regexp = "\\d+\\.\\d+\\.\\d+\\.\\d+";
	private static final String http_regexp = "(http|https|ftp)://([^/:]+)(:\\d*)?([^#\\s]*)";
	private static final String date_regexp = "^((((1[6-9]|[2-9]\\d)\\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-0?2-(0?[1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$";
	private static final String phone_regexp = "(\\+\\d+)?(\\d{3,4}\\-?)?\\d{7,8}$";
	private static final String mobile_phone_regexp = "(\\+\\d+)?1[3458]\\d{9}$";
	private static final String ID_card_regexp = "^\\d{10}|\\d{13}|\\d{15}|\\d{18}$";
	private static final String postcode_regexp = "^[0-9]{6}$";
	private static final String integer_regexp = "^-?\\d+$";
	private static final String rational_numbers_regexp = "^(-?\\d+)(\\.\\d+)?$";
	private static final String english_number = "^[a-z0-9A-Z]{5,20}";
	private static final String codeAndMobile = "^\\+[0-9]{2}\\-(13|15|18|17|16)[0-9]{9}$";
	/** 整数 */
	private static final String intege = "^-?[1-9]\\d*$";
	/** 正整数 */
	private static final String intege1 = "^[1-9]\\d*$";
	/** 负整数 */
	private static final String intege2 = "^-[1-9]\\d*$";
	/** 数字 */
	private static final String num = "^([+-]?)\\d*\\.?\\d+$";
	/** 正数（正整数 + 0） */
	private static final String num1 = "^[1-9]\\d*|0$";
	/** 负数（负整数 + 0） */
	private static final String num2 = "^-[1-9]\\d*|0$";
	/** 浮点数 */
	private static final String decmal = "^([+-]?)\\d*\\.\\d+$";
	/** 正浮点数 */
	private static final String decmal1 = "^[1-9]\\d*.\\d*|0.\\d*[1-9]\\d*$";
	/** 负浮点数 */
	private static final String decmal2 = "^-([1-9]\\d*.\\d*|0.\\d*[1-9]\\d*)$";
	/** 浮点数 */
	private static final String decmal3 = "^-?([1-9]\\d*.\\d*|0.\\d*[1-9]\\d*|0?.0+|0)$";
	/** 非负浮点数（正浮点数 + 0） */
	private static final String decmal4 = "^[1-9]\\d*.\\d*|0.\\d*[1-9]\\d*|0?.0+|0$";
	/** 非正浮点数（负浮点数 + 0） */
	private static final String decmal5 = "^(-([1-9]\\d*.\\d*|0.\\d*[1-9]\\d*))|0?.0+|0$";
	/** 邮件 */
	private static final String email = "^\\w+((-\\w+)|(\\.\\w+))*\\@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+$";
	/** 颜色 */
	private static final String color = "^[a-fA-F0-9]{6}$";
	/** url */
	private static final String url = "^http[s]?=\\/\\/([\\w-]+\\.)+[\\w-]+([\\w-./?%&=]*)?$";
	/** 仅中文 */
	private static final String chinese = "^[\\u4E00-\\u9FA5\\uF900-\\uFA2D]+$";
	/** 非仅中文 */
	private static final String not_chinese = "^[\u4e00-\u9fa5]+$";
	/** 仅ACSII字符 */
	private static final String ascii = "^[\\x00-\\xFF]+$";
	/** 邮编 */
	private static final String zipcode = "^\\d{6}$";
	/** ip地址 */
	private static final String ip4 = "^(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)$";
	/** 非空 */
	private static final String notempty = "^\\S+$";
	/** 图片 */
	private static final String picture = "(.*)\\.(jpg|bmp|gif|ico|pcx|jpeg|tif|png|raw|tga)$";
	/** 压缩文件 */
	private static final String rar = "(.*)\\.(rar|zip|7zip|tgz)$";
	/** 日期 */
	private static final String date = "^\\d{4}(\\-|\\/|\\.)\\d{1,2}\\1\\d{1,2}$";
	/** QQ号码 */
	private static final String qq = "^[1-9]*[1-9][0-9]*$";
	/** 电话号码的函数(包括验证国内区号;国际区号;分机号) */
	private static final String tel = "^(([0\\+]\\d{2,3}-)?(0\\d{2,3})-)?(\\d{7,8})(-(\\d{1,}))?$";
	/** 用来用户注册。匹配由数字、26个英文字母或者下划线组成的字符串 */
	private static final String username = "^\\w+$";
	/** 字母 */
	private static final String letter = "^[A-Za-z]+$";
	private static final String letterAndSpace = "^[A-Za-z ]+$";
	/** 大写字母 */
	private static final String letter_u = "^[A-Z]+$";
	/** 小写字母 */
	private static final String letter_l = "^[a-z]+$";
	/** 身份证 */
	private static final String idcard = "^[1-9]([0-9]{14}|[0-9]{17})$";
	/** 判断字符串是否为浮点数 */
	private static final String isFloat = "^[-]?\\d+(\\.\\d+)?$";
	/** 判断字符串是否为正浮点数 */
	private static final String isUFloat = "^\\d+(\\.\\d+)?$";
	/** 判断是否是整数 */
	private static final String isInteger = "^[-]?\\d+$";
	/** 判断是否是正整数 */
	private static final String isUInteger = "^\\d+$";
	/** 只能以字母开头,字母数字下划线组合,6-20位 **/
	private static final String account = "^[a-zA-Z]{1}([a-zA-Z0-9]|[_]){5,20}$";

	public static boolean isCodeAndMobile(String input) {
		return matches(codeAndMobile, input);
	}

	/** 整数 */
	public static boolean isIntege(String input) {
		return matches(intege, input);
	}

	/** 正整数 */
	public static boolean isintege1(String input) {
		return matches(intege1, input);
	}

	/** 负整数 */
	public static boolean isIntege2(String input) {
		return matches(intege2, input);
	}

	/** 数字 */
	public static boolean isNum(String input) {
		return matches(num, input);
	}

	/** 正数（正整数 + 0） */
	public static boolean isNum1(String input) {
		return matches(num1, input);
	}

	/** 负数（负整数 + 0） */
	public static boolean isNum2(String input) {
		return matches(num2, input);
	}

	/** 浮点数 */
	public static boolean isDecmal(String input) {
		return matches(decmal, input);
	}

	/** 正浮点数 */
	public static boolean isDecmal1(String input) {
		return matches(decmal1, input);
	}

	/** 负浮点数 */
	public static boolean isDecmal2(String input) {
		return matches(decmal2, input);
	}

	/** 浮点数 */
	public static boolean isDecmal3(String input) {
		return matches(decmal3, input);
	}

	/** 非负浮点数（正浮点数 + 0） */
	public static boolean isDecmal4(String input) {
		return matches(decmal4, input);
	}

	/** 非正浮点数（负浮点数 + 0） */
	public static boolean isDecmal5(String input) {
		return matches(decmal5, input);
	}

	/** 邮件 */
	public static boolean isEmail(String input) {
		return matches(email, input);
	}

	/** 颜色 */
	public static boolean isColor(String input) {
		return matches(color, input);
	}

	/** url */
	public static boolean isUrl(String input) {
		return matches(url, input);
	}

	/** 中文 */
	public static boolean isChinese(String input) {
		return matches(chinese, input);
	}

	/** 非中文 */
	public static boolean isNotChinese(String input) {
		return matches(not_chinese, input);
	}

	/** ascii码 */
	public static boolean isAscii(String input) {
		return matches(ascii, input);
	}

	/** 邮编 */
	public static boolean isZipcode(String input) {
		return matches(zipcode, input);
	}

	/** IP地址 */
	public static boolean isIP4(String input) {
		return matches(ip4, input);
	}

	/** 非空 */
	public static boolean isNotEmpty(String input) {
		return matches(notempty, input);
	}

	/** 图片 */
	public static boolean isPicture(String input) {
		return matches(picture, input);
	}

	/** 压缩文件 */
	public static boolean isRar(String input) {
		return matches(rar, input);
	}

	/** 日期 */
	public static boolean isDate(String input) {
		return matches(date, input);
	}

	/** qq */
	public static boolean isQQ(String input) {
		return matches(qq, input);
	}

	/** 电话号码的函数(包括验证国内区号;国际区号;分机号) */
	public static boolean isTel(String input) {
		return matches(tel, input);
	}

	/** 用来用户注册。匹配由数字、26个英文字母或者下划线组成的字符串 */
	public static boolean isUserName(String input) {
		return matches(username, input);
	}

	/** 字母 */
	public static boolean isLetter(String input) {
		return matches(letter, input);
	}

	public static boolean isLetterAndSpace(String input) {
		return matches(letterAndSpace, input);
	}

	/** 小写字母 */
	public static boolean isLowLetter(String input) {
		return matches(letter_l, input);
	}

	/** 大写字母 */
	public static boolean isUpperLetter(String input) {
		return matches(letter_u, input);
	}

	/** 身份证 */
	public static boolean isIDCard(String input) {
		return matches(idcard, input);
	}

	public static boolean isFloat(String input) {
		return matches(isFloat, input);
	}

	public static boolean isUFloat(String input) {
		return matches(isUFloat, input);
	}

	public static boolean isInteger(String input) {
		return matches(isInteger, input);
	}

	public static boolean isUInteger(String input) {
		return matches(isUInteger, input);
	}

	public static boolean isYouanAccount(String input) {
		return matches(account, input);
	}

	public static boolean matches(String regex, String input) {
		if (StringUtils.isBlank(input))
			return false;
		if (input.matches(regex))
			return true;
		return false;
	}

	/**
	 * 匹配5-20个英文数字
	 */
	public static boolean isEnglishNumber(String str) {
		return Pattern.matches(english_number, str);
	}

	/**
	 * 验证身份证号码
	 * 
	 * @param idCard
	 *            居民身份证号码15位或18位，最后一位可能是数字或字母
	 */
	public static boolean isIdCard(String idCard) {
		return Pattern.matches(ID_card_regexp, idCard);
	}

	/**
	 * 验证手机号码（支持国际格式，+86135xxxx...（中国内地），+00852137xxxx...（中国香港））
	 *
	 * @param mobile
	 *            移动、联通、电信运营商的号码段
	 *            <p>
	 *            移动的号段：134(0-8)、135、136、137、138、139、147（预计用于TD上网卡） 、150、151、152、157（TD专用）、158、159、187（未启用）、188（TD专用）
	 *            </p>
	 *            <p>
	 *            联通的号段：130、131、132、155、156（世界风专用）、185（未启用）、186（3g）
	 *            </p>
	 *            <p>
	 *            电信的号段：133、153、180（未启用）、189
	 *            </p>
	 * @return 验证成功返回true，验证失败返回false
	 */
	public static boolean isMobile(String mobile) {
		return Pattern.matches(mobile_phone_regexp, mobile);
	}

	/**
	 * 验证固定电话号码
	 *
	 * @param phone
	 *            电话号码，格式：国家（地区）电话代码 + 区号（城市代码） + 电话号码，如：+8602085588447
	 *            <p>
	 *            <b>国家（地区） 代码 ：</b>标识电话号码的国家（地区）的标准国家（地区）代码。它包含从 0 到 9 的一位或多位数字， 数字之后是空格分隔的国家（地区）代码。
	 *            </p>
	 *            <p>
	 *            <b>区号（城市代码）：</b>这可能包含一个或多个从 0 到 9 的数字，地区或城市代码放在圆括号—— 对不使用地区或城市代码的国家（地区），则省略该组件。
	 *            </p>
	 *            <p>
	 *            <b>电话号码：</b>这包含从 0 到 9 的一个或多个数字
	 *            </p>
	 * @return 验证成功返回true，验证失败返回false
	 */
	public static boolean checkPhone(String phone) {
		return Pattern.matches(phone_regexp, phone);
	}

	/**
	 * 验证整数（正整数和负整数）
	 * 
	 * @param digit
	 *            一位或多位0-9之间的整数
	 */
	public static boolean checkDigit(String digit) {
		return Pattern.matches(integer_regexp, digit);
	}

	/**
	 * 验证整数和浮点数（正负整数和正负浮点数）
	 *
	 * @param decimals
	 *            一位或多位0-9之间的浮点数，如：1.23，233.30
	 */
	public static boolean checkDecimals(String decimals) {
		return Pattern.matches(rational_numbers_regexp, decimals);
	}

	/**
	 * 验证空白字符
	 *
	 * @param blankSpace
	 *            空白字符，包括：空格、\t、\n、\r、\f、\x0B
	 */
	public static boolean checkBlankSpace(String blankSpace) {
		return Pattern.matches(blankSpace_regexp, blankSpace);
	}

	/**
	 * 验证中文
	 *
	 * @param chinese
	 *            中文字符
	 */
	public static boolean checkChinese(String chinese) {
		return Pattern.matches(chinese_regexp, chinese);
	}

	/**
	 * 验证生日日期（年月日）
	 * 
	 * @param birthday
	 *            日期，格式：1992-09-03，或1992.09.03
	 */
	public static boolean checkBirthday(String birthday) {
		return Pattern.matches(date_regexp, birthday);
	}

	/**
	 * 验证URL地址
	 */
	public static boolean checkURL(String url) {
		return Pattern.matches(http_regexp, url);
	}

	/**
	 * 匹配中国邮政编码
	 */
	public static boolean checkPostcode(String postcode) {
		return Pattern.matches(postcode_regexp, postcode);
	}

	/**
	 * 匹配IP地址
	 */
	public static boolean checkIpAddress(String ipAddress) {
		return Pattern.matches(ip_regexp, ipAddress);
	}

	public static boolean checkRegex(String regex, String ipAddress) {
		return Pattern.matches(ip_regexp, ipAddress);
	}
}
